package edu.pw.p2pclient.logic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.util.Log;
import edu.pw.p2pclient.data.Node;
import edu.pw.p2pclient.data.Node.SharingInfo;
import edu.pw.p2pclient.data.Resource;
import edu.pw.p2pclient.data.TreeNode;
import edu.pw.p2pclient.utils.ApplicationContext;

public class SharedManager {

	public static final long UNKNOWN_RESOURCE_LIST_VERSION = 0;

	private static final String TAG = "SharedManager";
	private static final String DATA_FILE = "/shared.dat";

	private static SharedManager mInstance = null;
	private TreeNode mRoot;
	private long mListVersion;

	private SharedManager() {
		try {
			FileInputStream fin = new FileInputStream(ApplicationContext.get()
					.getFilesDir().getParent()
					+ DATA_FILE);
			ObjectInputStream ois = new ObjectInputStream(fin);
			mRoot = (TreeNode) ois.readObject();
			ois.close();
			Log.i(TAG, "Shared nodes loaded from file successfully.");
		} catch (FileNotFoundException ex) {
			mRoot = new TreeNode();
		} catch (Exception ex) {
			Log.e(TAG, "Shared nodes could not be loaded from file.");
			ex.printStackTrace();
			mRoot = new TreeNode();
		}
		updateListVersion();
	}

	public static SharedManager getInstance() {
		if (mInstance == null)
			mInstance = new SharedManager();
		return mInstance;
	}

	public void updateListVersion() {
		mListVersion = System.currentTimeMillis();
	}

	public void addToShared(ArrayList<Node> nodes, boolean btShared,
			boolean wifiShared, boolean push, String pass) {

		if (!wifiShared && !btShared && !push) {
			removeFromShared(nodes);
		} else {
			for (Node node : nodes) {
				node.calcCrc();
				node.setSharingInfo(btShared, wifiShared, push, pass);
				addToShared(node);
			}
		}
		updateListVersion();
		saveSharedList();
	}

	private void addToShared(Node node) {
		mRoot.addChild(new TreeNode(node));
		if (!node.isFile()) {
			File root = new File(node.getFullPath());
			File files[] = root.listFiles();
			if (files != null)
				for (File file : files)
					addToShared(new Node(file, node.getSharingInfo()));
		}
	}

	public void removeFromShared(ArrayList<Node> nodes) {
		for (Node node : nodes) {
			node.resetSharingInfo();
			mRoot.removeChild(node);
		}
		updateListVersion();
		saveSharedList();
	}

	public HashMap<String, Node> getSharedFrom(String path) {
		return mRoot.getItemsFrom(path);
	}

	public Node getShared(Resource res) {
		return mRoot.getChild(res);
	}

	public SharingInfo getSharingInfo(String parentPath, String name) {

		for (Node node : mRoot.getItemsFrom(parentPath).values()) {
			if (node.getName().equals(name))
				return node.getSharingInfo();
		}
		return null;
	}

	public ArrayList<Node> getAllShared() {
		return mRoot.getShared(true, true, true);
	}

	public ArrayList<Node> getBtWifiShared() {
		return mRoot.getShared(true, true, false);
	}

	public ArrayList<Node> getPushShared() {
		return mRoot.getShared(false, false, true);
	}

	public long getListVersion() {
		return mListVersion;
	}

	public boolean isShared(Resource resource) {
		return getBtWifiShared().contains(resource);
	}

	public void saveSharedList() {
		try {
			FileOutputStream fout = new FileOutputStream(ApplicationContext
					.get().getFilesDir().getParent()
					+ DATA_FILE);
			ObjectOutputStream oos = new ObjectOutputStream(fout);
			oos.writeObject(mRoot);
			oos.close();
			Log.i(TAG, "Shared nodes saved to file successfully.");
		} catch (Exception ex) {
			Log.e(TAG, "Shared nodes could not be saved to file.");
			ex.printStackTrace();
		}
	}

}
